home *** CD-ROM | disk | FTP | other *** search
- #define LIBQBUILD_CORE
- #include "../include/libqbuild.h"
-
- //JIM
- struct entity *CurrentEntity; // 4
-
- vec3_t brush_mins, brush_maxs; // 24
- struct visfacet *brush_faces; // 4
-
- vec3_t hull_size[3][2] = // 72
- {
- {
- {0, 0, 0},
- {0, 0, 0}},
- {
- {-16, -16, -32},
- {16, 16, 24}},
- {
- {-32, -32, -64},
- {32, 32, 24}}
- };
-
- int num_hull_points; // 4
- vec3_t hull_points[MAX_HULL_POINTS]; // 384
- vec3_t hull_corners[MAX_HULL_POINTS * 8]; // 3072
- int num_hull_edges; // 4
- int hull_edges[MAX_HULL_EDGES][2]; // 512
-
- //===========================================================================
-
- /*
- * =================
- * CheckFace
- *
- * Note: this will not catch 0 area polygons
- * =================
- */
- void CheckFace(__memBase, register struct visfacet * f)
- {
- int i, j;
- vec_t *p1, *p2;
- vec_t d, edgedist;
- vec3_t dir, edgenormal, facenormal;
-
- if (f->numpoints < 3)
- Error("CheckFace: %i points", f->numpoints);
-
- #ifdef EXHAUSIVE_CHECK
- if(f->planenum >= bspMem->numbrushplanes || f->planenum < 0)
- Error("looking for nonexisting plane %d\n", f->planenum);
- #endif
- VectorCopy(bspMem->brushplanes[f->planenum].normal, facenormal);
- if (f->planeside) {
- VectorNegate(facenormal);
- }
-
- for (i = 0; i < f->numpoints; i++) {
- p1 = f->pts[i];
-
- for (j = 0; j < 3; j++)
- if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
- Error("CheckFace: BUGUS_RANGE: %g", p1[j]);
-
- j = i + 1 == f->numpoints ? 0 : i + 1;
-
- // check the point is on the face plane
- d = DotProduct(p1, bspMem->brushplanes[f->planenum].normal) - bspMem->brushplanes[f->planenum].dist;
- // if (d < -ON_EPSILON || d > ON_EPSILON)
- // Error ("CheckFace: point off plane");
- //MED
- if (d < -1 || d > 1)
- Error("CheckFace: point off plane d=%f", d);
-
- // check the edge isn't degenerate
- p2 = f->pts[j];
- VectorSubtract(p2, p1, dir);
-
- if (VectorLength(dir) < ON_EPSILON)
- Error("CheckFace: degenerate edge");
-
- CrossProduct(facenormal, dir, edgenormal);
- VectorNormalize(edgenormal);
- edgedist = DotProduct(p1, edgenormal);
- edgedist += ON_EPSILON;
-
- // all other points must be on front side
- #ifndef BETTER_BRANCH
- for (j = 0; j < f->numpoints; j++) {
- if (j == i)
- continue;
- d = DotProduct(f->pts[j], edgenormal);
- if (d > edgedist)
- Error("CheckFace: non-convex");
- }
- #else
- for (j = 0; j < i; j++)
- if (DotProduct(f->pts[j], edgenormal) > edgedist)
- Error("CheckFace: non-convex");
- for (j++; j < f->numpoints; j++)
- if (DotProduct(f->pts[j], edgenormal) > edgedist)
- Error("CheckFace: non-convex");
- #endif
- }
- }
-
- //===========================================================================
-
- /*
- * =================
- * ClearBounds
- * =================
- */
- void ClearBounds(register struct brushset * bs)
- {
- short int i, j;
-
- //for (j = 0; j < NUM_HULLS; j++) {
- #ifndef BETTER_BRANCH
- for (i = 0; i < 3; i++) {
- bs->mins[i] = 99999;
- bs->maxs[i] = -99999;
- }
- #else
- bs->mins[0] = 99999;
- bs->mins[1] = 99999;
- bs->mins[2] = 99999;
- bs->maxs[0] = -99999;
- bs->maxs[1] = -99999;
- bs->maxs[2] = -99999;
- #endif
- //}
- }
-
- /*
- * =================
- * AddToBounds
- * =================
- */
- void AddToBounds(register struct brushset * bs, register vec3_t v)
- {
- short int i;
-
- for (i = 0; i < 3; i++) {
- if (v[i] < bs->mins[i])
- bs->mins[i] = v[i];
- else if (v[i] > bs->maxs[i])
- bs->maxs[i] = v[i];
- }
- }
-
- //===========================================================================
-
- int PlaneTypeForNormal(vec3_t normal)
- {
- float ax, ay, az;
-
- // NOTE: should these have an epsilon around 1.0?
- if (normal[0] == 1.0)
- return PLANE_X;
- if (normal[1] == 1.0)
- return PLANE_Y;
- if (normal[2] == 1.0)
- return PLANE_Z;
- if (normal[0] == -1.0 ||
- normal[1] == -1.0 ||
- normal[2] == -1.0)
- Error("PlaneTypeForNormal: not a canonical vector");
-
- ax = fabs(normal[0]);
- ay = fabs(normal[1]);
- az = fabs(normal[2]);
-
- if (ax >= ay && ax >= az)
- return PLANE_ANYX;
- if (ay >= ax && ay >= az)
- return PLANE_ANYY;
- return PLANE_ANYZ;
- }
-
- void NormalizePlane(register struct plane * dp)
- {
- vec_t ax, ay, az;
-
- if (dp->normal[0] == -1.0) {
- dp->normal[0] = 1.0;
- dp->dist = -dp->dist;
- }
- if (dp->normal[1] == -1.0) {
- dp->normal[1] = 1.0;
- dp->dist = -dp->dist;
- }
- if (dp->normal[2] == -1.0) {
- dp->normal[2] = 1.0;
- dp->dist = -dp->dist;
- }
-
- if (dp->normal[0] == 1.0) {
- dp->type = PLANE_X;
- return;
- }
- if (dp->normal[1] == 1.0) {
- dp->type = PLANE_Y;
- return;
- }
- if (dp->normal[2] == 1.0) {
- dp->type = PLANE_Z;
- return;
- }
-
- ax = fabs(dp->normal[0]);
- ay = fabs(dp->normal[1]);
- az = fabs(dp->normal[2]);
-
- if (ax >= ay && ax >= az)
- dp->type = PLANE_ANYX;
- else if (ay >= ax && ay >= az)
- dp->type = PLANE_ANYY;
- else
- dp->type = PLANE_ANYZ;
- if (dp->normal[dp->type - PLANE_ANYX] < 0) {
- VectorNegate(dp->normal);
- dp->dist = -dp->dist;
- }
-
- }
-
- /*
- * ===============
- * FindPlane
- *
- * Returns a global plane number and the side that will be the front
- * ===============
- */
- int FindPlane(__memBase, register struct plane *dplane, register int *side)
- {
- int i;
- struct plane *dp, pl;
- vec_t dot;
-
- dot = VectorLength(dplane->normal);
- if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
- Error("FindPlane: normalization error");
-
- pl = *dplane;
- NormalizePlane(&pl);
- if (DotProduct(pl.normal, dplane->normal) > 0)
- *side = 0;
- else
- *side = 1;
-
- dp = bspMem->brushplanes;
- for (i = 0; i < bspMem->numbrushplanes; i++, dp++) {
- dot = DotProduct(dp->normal, pl.normal);
- if (dot > 1.0 - ANGLEEPSILON
- && fabs(dp->dist - pl.dist) < DISTEPSILON) { // regular match
- return i;
- }
- }
-
- if (bspMem->numbrushplanes == bspMem->max_numbrushplanes)
- ExpandClusters(bspMem, MAP_BRUSHPLANES);
- bspMem->brushplanes[bspMem->numbrushplanes] = pl;
- bspMem->numbrushplanes++;
-
- return bspMem->numbrushplanes - 1;
- }
-
- /*
- * ===============
- * FindPlane_old
- *
- * Returns a global plane number and the side that will be the front
- * ===============
- */
- int FindPlane_old(__memBase, register struct plane * dplane, register int *side)
- {
- int i;
- struct plane *dp;
- vec_t dot, ax, ay, az;
-
- dot = VectorLength(dplane->normal);
- if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
- Error("FindPlane: normalization error");
-
- dp = bspMem->brushplanes;
-
- for (i = 0; i < bspMem->numbrushplanes; i++, dp++) {
- dot = DotProduct(dplane->normal, dp->normal);
- if (dot > 1.0 - ANGLEEPSILON
- && fabs(dplane->dist - dp->dist) < DISTEPSILON) { // regular match
-
- *side = 0;
- return i;
- }
- if (dot < -1.0 + ANGLEEPSILON
- && fabs(dplane->dist + dp->dist) < DISTEPSILON) { // inverse of vector
-
- *side = 1;
- return i;
- }
- }
-
- // allocate a new plane, flipping normal to a consistant direction
- // if needed
- *dp = *dplane;
-
- if (bspMem->numbrushplanes == bspMem->max_numbrushplanes)
- ExpandClusters(bspMem, MAP_BRUSHPLANES);
- bspMem->numbrushplanes++;
-
- *side = 0;
-
- // NOTE: should these have an epsilon around 1.0?
- if (dplane->normal[0] == 1.0)
- dp->type = PLANE_X;
- else if (dplane->normal[1] == 1.0)
- dp->type = PLANE_Y;
- else if (dplane->normal[2] == 1.0)
- dp->type = PLANE_Z;
- else if (dplane->normal[0] == -1.0) {
- dp->type = PLANE_X;
- dp->normal[0] = 1.0;
- dp->dist = -dp->dist;
- *side = 1;
- }
- else if (dplane->normal[1] == -1.0) {
- dp->type = PLANE_Y;
- dp->normal[1] = 1.0;
- dp->dist = -dp->dist;
- *side = 1;
- }
- else if (dplane->normal[2] == -1.0) {
- dp->type = PLANE_Z;
- dp->normal[2] = 1.0;
- dp->dist = -dp->dist;
- *side = 1;
- }
- else {
- ax = fabs(dplane->normal[0]);
- ay = fabs(dplane->normal[1]);
- az = fabs(dplane->normal[2]);
-
- if (ax >= ay && ax >= az)
- dp->type = PLANE_ANYX;
- else if (ay >= ax && ay >= az)
- dp->type = PLANE_ANYY;
- else
- dp->type = PLANE_ANYZ;
- if (dplane->normal[dp->type - PLANE_ANYX] < 0) {
- VectorNegate(dp->normal);
- dp->dist = -dp->dist;
- *side = 1;
- }
- }
-
- return i;
- }
-
- /*
- * =============================================================================
- *
- * TURN BRUSHES INTO GROUPS OF FACES
- *
- * =============================================================================
- */
-
- /*
- * =================
- * CreateBrushFaces
- * =================
- */
- void CreateBrushFaces(__memBase)
- {
- int i, j;
- short int k;
- vec_t r;
- struct visfacet *f;
- struct winding *w;
- struct plane plane;
- struct mface *mf;
-
- //JIM
- vec3_t offset;
- vec3_t point;
- vec_t max;
- vec_t min;
-
- //JIM
- offset[0] = offset[1] = offset[2] = 0;
- brush_mins[0] = brush_mins[1] = brush_mins[2] = 99999;
- brush_maxs[0] = brush_maxs[1] = brush_maxs[2] = -99999;
-
- brush_faces = NULL;
-
- //JIM
- if (!strncmp(CurrentEntity->classname, "rotate_", 7)) {
- char text[32];
- if (CurrentEntity->targetent) {
- GetVectorForKey(CurrentEntity->targetent, "origin", offset);
- sprintf(text, "%g %g %g", offset[0], offset[1], offset[2]);
- SetKeyValue(CurrentEntity, "origin", text);
- }
- }
-
- for (i = 0; i < bspMem->numbrushfaces; i++) {
- mf = &bspMem->brushfaces[i];
-
- w = BaseWindingForPlane(&mf->plane);
- /*
- * if (!w)
- * printf("basewinding failed\n");
- */
-
- for (j = 0; j < bspMem->numbrushfaces && w; j++) {
- if (j == i)
- continue;
- // flip the plane, because we want to keep the back side
- VectorNegateTo(bspMem->brushfaces[j].plane.normal, plane.normal);
- plane.dist = -bspMem->brushfaces[j].plane.dist;
-
- w = ClipWinding(w, &plane, FALSE);
- /*
- * if (!w)
- * printf("clipwinding failed\n");
- */
- }
-
- if (!w) {
- /*
- * printf("overcontrained plane\n");
- */
- continue; // overcontrained plane
- }
-
- // this face is a keeper
- f = AllocFace(w->numpoints);
- f->numpoints = w->numpoints;
- if (f->numpoints > MAXEDGES)
- Error("f->numpoints > MAXEDGES");
-
- // mprintf("CreateBrushFaces: make face with %d points\n", f->numpoints);
-
- for (j = 0; j < w->numpoints; j++) {
- for (k = 0; k < 3; k++) {
- //JIM
- point[k] = w->points[j][k] - offset[k];
- r = rint(point[k]);
- if (fabs(point[k] - r) < ZERO_EPSILON)
- f->pts[j][k] = r;
- else
- f->pts[j][k] = point[k];
-
- if (f->pts[j][k] < brush_mins[k])
- brush_mins[k] = f->pts[j][k];
- if (f->pts[j][k] > brush_maxs[k])
- brush_maxs[k] = f->pts[j][k];
- if (f->pts[j][k] < min)
- min = f->pts[j][k];
- if (f->pts[j][k] > max)
- max = f->pts[j][k];
- }
-
- }
- //JIM
- VectorCopy(mf->plane.normal, plane.normal);
- VectorScale(mf->plane.normal, mf->plane.dist, point);
- VectorSubtract(point, offset, point);
- plane.dist = DotProduct(plane.normal, point);
-
- FreeWinding(w);
- f->texturenum = mf->texinfo;
- //JIM
- f->planenum = FindPlane(bspMem, &plane, &f->planeside);
- // f->planenum = FindPlane (&mf->plane, &f->planeside);
- f->next = brush_faces;
- brush_faces = f;
- CheckFace(bspMem, f);
- }
-
- // Rotatable objects have to have a bounding box big enough
- // to account for all its rotations.
- if (!strncmp(CurrentEntity->classname, "rotate_", 7)) {
- vec_t delta;
-
- delta = fabs(max);
- if (fabs(min) > delta)
- delta = fabs(min);
-
- for (k = 0; k < 3; k++) {
- brush_mins[k] = -delta;
- brush_maxs[k] = delta;
- }
- }
- }
-
- /*
- * ==============================================================================
- *
- * BEVELED CLIPPING HULL GENERATION
- *
- * This is done by brute force, and could easily get a lot faster if anyone cares.
- * ==============================================================================
- */
-
- /*
- * ============
- * AddBrushPlane
- * =============
- */
- void AddBrushPlane(__memBase, register struct plane * plane)
- {
- int i;
- struct plane *pl;
- float l;
-
- if (bspMem->numbrushfaces == bspMem->max_numbrushfaces)
- ExpandClusters(bspMem, MAP_BRUSHFACES);
-
- l = VectorLength(plane->normal);
- if (l < 0.999 || l > 1.001)
- Error("AddBrushPlane: bad normal");
-
- for (i = 0; i < bspMem->numbrushfaces; i++) {
- pl = &bspMem->brushfaces[i].plane;
- if (VectorCompare(pl->normal, plane->normal)
- && fabs(pl->dist - plane->dist) < ON_EPSILON)
- return;
- }
- bspMem->brushfaces[i].plane = *plane;
- bspMem->brushfaces[i].texinfo = bspMem->brushfaces[0].texinfo;
- bspMem->numbrushfaces++;
- }
-
- /*
- * ============
- * TestAddPlane
- *
- * Adds the given plane to the brush description if all of the original brush
- * vertexes can be put on the front side
- * =============
- */
- void TestAddPlane(__memBase, register struct plane * plane)
- {
- int i, c;
- vec_t d;
- vec_t *corner;
- struct plane flip;
- vec3_t inv;
- int counts[3];
- struct plane *pl;
-
- // see if the plane has allready been added
- for (i = 0; i < bspMem->numbrushfaces; i++) {
- pl = &bspMem->brushfaces[i].plane;
- if (VectorCompare(plane->normal, pl->normal) && fabs(plane->dist - pl->dist) < ON_EPSILON)
- return;
- VectorNegateTo(plane->normal, inv);
- if (VectorCompare(inv, pl->normal) && fabs(plane->dist + pl->dist) < ON_EPSILON)
- return;
- }
-
- // check all the corner points
- counts[0] = counts[1] = counts[2] = 0;
- c = num_hull_points * 8;
-
- corner = hull_corners[0];
- for (i = 0; i < c; i++, corner += 3) {
- d = DotProduct(corner, plane->normal) - plane->dist;
- if (d < -ON_EPSILON) {
- if (counts[0])
- return;
- counts[1]++;
- }
- else if (d > ON_EPSILON) {
- if (counts[1])
- return;
- counts[0]++;
- }
- else
- counts[2]++;
- }
-
- // the plane is a seperator
-
- if (counts[0]) {
- VectorNegateTo(plane->normal, flip.normal);
- flip.dist = -plane->dist;
- plane = &flip;
- }
-
- AddBrushPlane(bspMem, plane);
- }
-
- /*
- * ============
- * AddHullPoint
- *
- * Doesn't add if duplicated
- * =============
- */
- int AddHullPoint(register vec3_t p, register int hullnum)
- {
- int i;
- vec_t *c;
- short int x, y, z;
-
- for (i = 0; i < num_hull_points; i++)
- if (VectorCompare(p, hull_points[i]))
- return i;
-
- VectorCopy(p, hull_points[num_hull_points]);
-
- c = hull_corners[i * 8];
-
- for (x = 0; x < 2; x++)
- for (y = 0; y < 2; y++)
- for (z = 0; z < 2; z++) {
- c[0] = p[0] + hull_size[hullnum][x][0];
- c[1] = p[1] + hull_size[hullnum][y][1];
- c[2] = p[2] + hull_size[hullnum][z][2];
- c += 3;
- }
-
- if (num_hull_points == MAX_HULL_POINTS)
- Error("MAX_HULL_POINTS");
-
- num_hull_points++;
-
- return i;
- }
-
- /*
- * ============
- * AddHullEdge
- *
- * Creates all of the hull planes around the given edge, if not done allready
- * =============
- */
- void AddHullEdge(__memBase, register vec3_t p1, register vec3_t p2, register int hullnum)
- {
- int pt1, pt2;
- int i;
- short int a, b, c, d, e;
- vec3_t edgevec, planeorg, planevec;
- struct plane plane;
- vec_t l;
-
- pt1 = AddHullPoint(p1, hullnum);
- pt2 = AddHullPoint(p2, hullnum);
-
- for (i = 0; i < num_hull_edges; i++)
- if ((hull_edges[i][0] == pt1 && hull_edges[i][1] == pt2)
- || (hull_edges[i][0] == pt2 && hull_edges[i][1] == pt1))
- return; // allread added
-
- if (num_hull_edges == MAX_HULL_EDGES)
- Error("MAX_HULL_EDGES");
-
- hull_edges[i][0] = pt1;
- hull_edges[i][1] = pt2;
- num_hull_edges++;
-
- VectorSubtract(p1, p2, edgevec);
- VectorNormalize(edgevec);
-
- for (a = 0; a < 3; a++) {
- b = (a + 1) % 3;
- c = (a + 2) % 3;
- for (d = 0; d <= 1; d++)
- for (e = 0; e <= 1; e++) {
- VectorCopy(p1, planeorg);
- planeorg[b] += hull_size[hullnum][d][b];
- planeorg[c] += hull_size[hullnum][e][c];
-
- VectorClear(planevec);
- planevec[a] = 1;
-
- CrossProduct(planevec, edgevec, plane.normal);
- l = VectorLength(plane.normal);
- if (l < 1 - ANGLEEPSILON || l > 1 + ANGLEEPSILON)
- continue;
- plane.dist = DotProduct(planeorg, plane.normal);
- TestAddPlane(bspMem, &plane);
- }
- }
-
- }
-
- /*
- * ============
- * ExpandBrush
- * =============
- */
- void ExpandBrush(__memBase, register int hullnum)
- {
- int i, s;
- short int x;
- vec3_t corner;
- struct visfacet *f;
- struct plane plane, *p;
-
- num_hull_points = 0;
- num_hull_edges = 0;
-
- // create all the hull points
- for (f = brush_faces; f; f = f->next)
- for (i = 0; i < f->numpoints; i++)
- AddHullPoint(f->pts[i], hullnum);
-
- // expand all of the planes
- for (i = 0; i < bspMem->numbrushfaces; i++) {
- p = &bspMem->brushfaces[i].plane;
- VectorClear(corner);
- for (x = 0; x < 3; x++) {
- if (p->normal[x] > 0)
- corner[x] = hull_size[hullnum][1][x];
- else if (p->normal[x] < 0)
- corner[x] = hull_size[hullnum][0][x];
- }
- p->dist += DotProduct(corner, p->normal);
- }
-
- // add any axis planes not contained in the brush to bevel off corners
- for (x = 0; x < 3; x++)
- for (s = -1; s <= 1; s += 2) {
- // add the plane
- VectorClear(plane.normal);
- plane.normal[x] = s;
- if (s == -1)
- plane.dist = -brush_mins[x] + -hull_size[hullnum][0][x];
- else
- plane.dist = brush_maxs[x] + hull_size[hullnum][1][x];
- AddBrushPlane(bspMem, &plane);
- }
-
- // add all of the edge bevels
- for (f = brush_faces; f; f = f->next)
- for (i = 0; i < f->numpoints; i++)
- AddHullEdge(bspMem, f->pts[i], f->pts[(i + 1) % f->numpoints], hullnum);
- }
-
- //============================================================================
-
- /*
- * ===============
- * LoadBrush
- *
- * Converts a mapbrush to a bsp brush
- * ===============
- */
- struct brush *LoadBrush(__memBase, register struct mbrush * mb, register int hullnum)
- {
- struct brush *b;
- int contents;
- char *name;
- struct mface *f;
-
- //
- // check texture name for attributes
- //
- name = bspMem->maptexstrings[bspMem->texinfo[mb->faces->texinfo].miptex];
-
- if (!strcasecmp(name, "clip") && hullnum == 0) {
- return NULL; // "clip" brushes don't show up in the draw hull
- }
-
- if (name[0] == '*' && worldmodel) // bspMem->mapentities never use water merging
- {
- if (!strncasecmp(name + 1, "lava", 4))
- contents = CONTENTS_LAVA;
- else if (!strncasecmp(name + 1, "slime", 5))
- contents = CONTENTS_SLIME;
- else
- contents = CONTENTS_WATER;
- }
- else if (!strncasecmp(name, "sky", 3) && worldmodel && hullnum == 0)
- contents = CONTENTS_SKY;
- else
- contents = CONTENTS_SOLID;
-
- if (hullnum && contents != CONTENTS_SOLID && contents != CONTENTS_SKY) {
- return NULL; // water brushes don't show up in clipping hulls
- }
-
- // no seperate textures on clip hull
-
- //
- // create the faces
- //
- brush_faces = NULL;
-
- bspMem->numbrushfaces = 0;
- for (f = mb->faces; f; f = f->next) {
- bspMem->brushfaces[bspMem->numbrushfaces] = *f;
- if (hullnum)
- bspMem->brushfaces[bspMem->numbrushfaces].texinfo = 0;
- bspMem->numbrushfaces++;
- }
-
- CreateBrushFaces(bspMem);
-
- if (!brush_faces) {
- eprintf("couldn't create brush faces\n");
- return NULL;
- }
-
- if (hullnum) {
- ExpandBrush(bspMem, hullnum);
- CreateBrushFaces(bspMem);
- }
-
- //
- // create the brush
- //
- b = AllocBrush();
-
- b->contents = contents;
- b->faces = brush_faces;
- VectorCopy(brush_mins, b->mins);
- VectorCopy(brush_maxs, b->maxs);
-
- return b;
- }
-
- //=============================================================================
-
- /*
- * ============
- * Brush_DrawAll
- *
- * ============
- */
- void Brush_DrawAll(register struct brushset * bs)
- {
- struct brush *b;
- struct visfacet *f;
-
- for (b = bs->brushes; b; b = b->next)
- for (f = b->faces; f; f = f->next)
- Draw_DrawFace(f);
- }
-
- #if 0
- /*
- * added by Niels
- */
- struct mbrush *FreeBrush(register struct mbrush *mbr) {
- struct mbrush *mn = mbr->next;
- struct mface *mf = mbr->faces;
- tfree(mbr);
- while(mf) {
- struct mface *mfn = mf->next;
- tfree(mf);
- mf = mfn;
- }
- return mn;
- }
- #endif
-
- /*
- * ============
- * Brush_LoadEntity
- * ============
- */
- struct brushset *Brush_LoadEntity(__memBase, struct entity * ent, int hullnum)
- {
- struct brush *b, *next, *water, *other;
- struct mbrush *mbr;
- int numbrushes, numbrushesp, i;
- struct brushset *bset;
-
- if(!(bset = (struct brushset *)tmalloc(sizeof(struct brushset))))
- Error("BrushLoadEntity: failed to allocate brushset!\n");
-
- ClearBounds(bset);
-
- numbrushes = 0;
- numbrushesp = 0;
- other = water = NULL;
-
- mprintf("----- BrushLoadEntity ---\n");
-
- CurrentEntity = ent;
-
- /* added by niels "mbr = FreeBrush(mbr)" */
- for (mbr = ent->brushes; mbr; mbr = mbr->next)
- numbrushesp++;
-
- for (mbr = ent->brushes, i = 0; mbr; mbr = mbr->next, i++) {
- if((b = LoadBrush(bspMem, mbr, hullnum))) {
- numbrushes++;
-
- if (b->contents != CONTENTS_SOLID) {
- b->next = water;
- water = b;
- }
- else {
- b->next = other;
- other = b;
- }
-
- AddToBounds(bset, b->mins);
- AddToBounds(bset, b->maxs);
- }
- mprogress(numbrushesp, i + 1);
- }
-
- // add all of the water textures at the start
- for (b = water; b; b = next) {
- next = b->next;
- b->next = other;
- other = b;
- }
-
- bset->brushes = other;
- /* PROGRESS-ONLY! */
- bset->numbrushes = numbrushes;
-
- brushset = bset;
- Brush_DrawAll(bset);
-
- mprintf("%5i brushes read\n", numbrushes);
-
- return bset;
- }
-